using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using RFS.BizLogic.PaiShi.Ports;
using RFS.BizLogic.PaiShi.Ports.Adapters;
using RFS.Domain.PaiShi;
using RFS.Domain.PaiShi.Accounting;
using RFS.Domain.PaiShi.WorkFlow;
using RFS.Domain.Sys;

namespace RFS.BizLogic.PaiShi.Accounting
{
    public class AccountingVoucherManager : IAccountingVoucherManager
    {
        // public IOrderItemBasedAccountingVoucher CreateAV(IOrderItem gho, IOrderItem yso=default)
        // {
        //     //1 create a av object and put it into 
        //
        //     var av = new OrderItemBasedAccountingVoucher();
        //
        //     if (gho != default)
        //     {
        //         av.AddAccItem(gho, Account.KCSP, $"供货_{gho.Product.Key}_{gho.BizId}" ,  amountDebit :  GetAmount(gho)  ); //j
        //
        //     }
        //
        //     if (yso != null)
        //     {
        //         av.AddAccItem(yso, Account.KCSP, $"验收_{yso.Product.Key}_{yso.BizId}" , amountCredit  :  GetAmount(yso)  ); //d
        //
        //     }
        //     
        //     
        //
        //     return av;
        // }

        // public IOrderItemBasedAccountingVoucher CreateAV( IEnumerable<IOrderItem> ghos,  IEnumerable<IOrderItem> ysos)
        // {
        //     //1 create a av object and put it into 
        //
        //     var av = new OrderItemBasedAccountingVoucher();
        //     
        //     foreach (var gho in ghos)
        //     {
        //         av.AddAccItem(gho, Account.KCSP, $"供货_{gho.Product.Key}_{gho.BizId}" ,  amountDebit :  GetAmount(gho)  ); //j
        //         (gho as OrderItem).RecordedInAcc = true;
        //     }
        //     foreach (var yso in ysos)
        //     {
        //         av.AddAccItem(yso, Account.KCSP, $"收货_{yso.Product.Key}_{yso.BizId}" , amountCredit  :  GetAmount(yso)  ); //d
        //         (yso as OrderItem).RecordedInAcc = true;
        //     }
        //     
        //     // av.State = VoucherState.自平;
        //     
        //     return av;
        // }




        public IDayBasedWorkFlowNodeAccountingVoucherSetWrapper CreateAVs()
        {


            IDayBasedWorkFlowNodeAccountingVoucherSetWrapper vs =
                new DayBasedWorkFlowNodeAccountingVoucherSetWrapper( this );


            _voucherSets[vs.AccPeriod.ToString()] = vs;
            return vs;

        }
        
       

        
        Dictionary<string,IDayBasedWorkFlowNodeAccountingVoucherSetWrapper> _voucherSets = new Dictionary<string, IDayBasedWorkFlowNodeAccountingVoucherSetWrapper>();
        
        public IOrderItemBasedAccountingVoucher GetMyVoucherByOrderId(string bizid,bool onlyLeft=true )
        {

            var bothside = !onlyLeft;
            
           var av= _voucherSets.Values.SelectMany(x => x.Vouchers)
                .FirstOrDefault(x => (x.AccItems
                    .Count(y => y.RelatedOrderItem.BizId == bizid && (bothside 
                                                                      ||  y.AmountCredit.Equals( new Amount(0,0) )  ) ) > 0  ))  ;
 
           return av;

        }

        
        IWorkFlowManager _workFlowManager;
        public IWorkFlowNodeWrapper GetHistoryUnRecorderOrder(AccountPeriod period)
        {
            
            return _workFlowManager.GetUnRecordedInAccYanShouNode(period);
            
            
        }

        IRepoPaiShi _repoPaiShi;
        public IDayBasedWorkFlowNodeAccountingVoucherSetWrapper GetDayBasedVoucherSet(AccountPeriod perio)
        {
           if (  _voucherSets.ContainsKey(perio.ToString()) )
               return _voucherSets[perio.ToString()];

           //load avs from db
           IDayBasedWorkFlowNodeAccountingVoucherSetWrapper res = _repoPaiShi.GetAVS(perio);

           return res;
        }

        public IWorkFlowNodeWrapper GetLeftNode(AccountPeriod period)
        {
 
            return _workFlowManager.GetByBatchNo(period.BeginDate.ToKey() , BizFlowNodeEnum.FaHuo);
            
        }
        public IWorkFlowNodeWrapper GetRightNode(AccountPeriod period,bool IncludeFromProductionLine=true, bool IncludeFromRegroup=false)
        {
 
            return  _workFlowManager.GetByYanShouNode(period.BeginDate.ToKey(),  fromProdLine: IncludeFromProductionLine, fromRegroup: IncludeFromRegroup);
             

        }

        


        private IPriceManagerPort _priceManagerPort;
        private IConfigT _config;

        public AccountingVoucherManager(IPriceManagerPort priceManagerPort, IConfigT config, IWorkFlowManager workFlowManager, IRepoPaiShi repoPaiShi)
        {
            _priceManagerPort = priceManagerPort;
            _config = config;
            _workFlowManager = workFlowManager;
            _repoPaiShi = repoPaiShi;
        }

        Amount GetAmount(IOrderItem orderItem)
        {
            // var price= _priceManagerPort.GetPrice(
            //     orderItem.BizTime,  
            //      orderItem.Product , 
            //     _config.ConfigSys.SmartChoosePrice );
            
            return new Amount( amount: orderItem.Amount ,quantity: orderItem.Quantity );
        }
    }
}